 /// @file ExchangeGDT.h
 /// @brief ExchangeGDT 
 /// @copyright Copyright (c) 2025  Hefei Jiushao Intelligent Technology Co., Ltd. All rights reserved.
 /// @createtime 2025-04-07

#ifndef EXCHANGECOREGDT_H
#define EXCHANGECOREGDT_H
#include "ExchangePMIBase.h"
#include <memory>
#include <vector>
#include "ExchangePMIDatum.h"
#include "pmi/ExchangePMIBase.h"

namespace  AMCAX::Exchange::Core::PMI {

enum class PMIToleranceType{
    UNKNOWN,

	// Form tolerance
	Form_Straightness,			  /**< Form_Straightness */
	Form_Flatness,				  /**< Form_Flatness */
	Form_Circularity,				  /**< Form_Circularity */
	Form_Cylindricity,			  /**< Form_Cylindricity */
	Form_ProfileAnyLine,			  /**< Form_ProfileAnyLine */
	Form_ProfileAnySurface,		  /**< Form_ProfileAnySurface */

	// Orientation tolerance
	Orientation_Parallelism,		  /**< Orientation_Parallelism */
	Orientation_Perpendicularity,	  /**< Orientation_Perpendicularity */
	Orientation_Angularity,		  /**< Orientation_Angularity */
											  /**<  */
	// Position tolerance
	Location_TruePosition,		  /**< Location_TruePosition */
	Location_Concentricity,		  /**< Location_Concentricity */
	Location_Coaxiality,			  /**< Location_Coaxiality */
	Location_Symmetry,			  /**< Location_Symmetry */
	Location_PositionOfAnyLine,	  /**< Location_PositionOfAnyLine */
	Location_PositionOfASurface,	  /**< Location_PositionOfASurface */

	// Run-out tolerance
	RunOut_Circular,				 /**< RunOut_Circular	*/
	RunOut_Total					 /**< RunOut_Total */
} ;

ENUM_TO_STRING_CASE_ALL(
    PMIToleranceType,
    
    ENUM_CASE(PMIToleranceType, UNKNOWN)

	// Form tolerance
	ENUM_CASE(PMIToleranceType, Form_Straightness)
	ENUM_CASE(PMIToleranceType, Form_Flatness)
	ENUM_CASE(PMIToleranceType, Form_Circularity)
	ENUM_CASE(PMIToleranceType, Form_Cylindricity)
	ENUM_CASE(PMIToleranceType, Form_ProfileAnyLine)
	ENUM_CASE(PMIToleranceType, Form_ProfileAnySurface)

	// Orientation tolerance
	ENUM_CASE(PMIToleranceType, Orientation_Parallelism)
	ENUM_CASE(PMIToleranceType, Orientation_Perpendicularity)
	ENUM_CASE(PMIToleranceType, Orientation_Angularity)
											  /**<  */
	// Position tolerance
	ENUM_CASE(PMIToleranceType, Location_TruePosition)
	ENUM_CASE(PMIToleranceType, Location_Concentricity)
	ENUM_CASE(PMIToleranceType, Location_Coaxiality)
	ENUM_CASE(PMIToleranceType, Location_Symmetry)
	ENUM_CASE(PMIToleranceType, Location_PositionOfAnyLine)
	ENUM_CASE(PMIToleranceType, Location_PositionOfASurface)

	// Run-out tolerance
	ENUM_CASE(PMIToleranceType, RunOut_Circular)
	ENUM_CASE(PMIToleranceType, RunOut_Total)
)

enum class PMIToleranceValueType{
    NONE,
    DIAMETER,
    RADIUS,
    SPHERICAL,
    SQUARE,
} ;
ENUM_TO_STRING_CASE_ALL(
    PMIToleranceValueType,
    
    ENUM_CASE(PMIToleranceValueType,NONE)
    ENUM_CASE(PMIToleranceValueType,DIAMETER)
    ENUM_CASE(PMIToleranceValueType,RADIUS)
    ENUM_CASE(PMIToleranceValueType,SPHERICAL)
    ENUM_CASE(PMIToleranceValueType,SQUARE)
)

enum class PMIToleranceModifierType{
    NoModifier,								/**< NoModifier */

	// Material conditions.
	MaterialCondition_Unsupported,			/**< MaterialCondition_Unsupported */
	MaterialCondition_NoModifier,				/**< MaterialCondition_NoModifier */
	MaterialCondition_Maximum,				/**< MaterialCondition_Maximum */
	MaterialCondition_Least,					/**< MaterialCondition_Least */
	MaterialCondition_RegardlessOfFeatureSize,/**< MaterialCondition_RegardlessOfFeatureSize */

	// Tangent planes
	TangentPlane_Unsupported,					/**< TangentPlane_Unsupported */
	TangentPlane_NotTangent,					/**< TangentPlane_NotTangent */
	TangentPlane_Tangent,						/**< TangentPlane_Tangent */

	// Free State
	FreeState_Unsupported,					/**< FreeState_Unsupported */
	FreeState_Free,							/**< FreeState_Free */
	FreeState_NotFree,						/**< FreeState_NotFree */

	//ST symbol
	Statistical_Symbol,						/**< Statistical_Symbol */

	//Common Zone
	CommonZone,								/**< CommonZone */


	//Unequally Disposed Tolerance Zone
	UnequallyDisposedZone,						/**< UnequallyDisposedZone */

	// Projected State
	ProjectedState_Projected,					/**< ProjectedState_Projected */
	ProjectedState_NotProjected,				/**< ProjectedState_NotProjected */

	// Circle U 
	CircleU,									/**< CircleU */

	Maximum,									/**< Maximum */
	MinimaxFeature,							/**< MinimaxFeature */
	DerivedFeature,							/**< DerivedFeature */
	DynamicProfile,							/**< DynamicProfile */
	LeastSquareFeature,						/**< LeastSquareFeature */
	MaximumInscribedFeature,					/**< MaximumInscribedFeature */
	MinimumCircumscribedFeature,				/**< MinimumCircumscribedFeature */

	SeparateZone,									/*SeparateZone*/
	OffsetZone,									/*OffsetZone*/
	VariableAngle,								/*VariableAngle*/
	OrientationConstraint,						/*OrientationConstraint*/
	MinimaxAssociation,							/*MinimaxAssociation*/
	MinimaxAssociationWithExternalConstraint,		/*MinimaxAssociationWithExternalConstraint*/
	MinimaxAssociationWithInternalConstraint,		/*MinimaxAssociationWithInternalConstraint*/
	LeastSquareAssociation,						/*LeastSquareAssociation*/
	LeastSquareAssociationWithExternalConstraint, /*LeastSquareAssociationWithExternalConstraint*/
	LeastSquareAssociationWithInternalConstraint, /*LeastSquareAssociationWithInternalConstraint*/
	MinimumCircumscribedAssociation,				/*MinimumCircumscribedAssociation*/
	MaximumInscribedAssociation,					/*MaximumInscribedAssociation*/
	TotalRangeOfDeviations,						/*TotalRangeOfDeviations*/
	PeakHeight,									/*PeakHeight*/
	ValleyDepth,									/*ValleyDepth*/
	StandardDeviation								/*StandardDeviation*/
} ;

ENUM_TO_STRING_CASE_ALL(
    PMIToleranceModifierType,
    
    ENUM_CASE(PMIToleranceModifierType,NoModifier)

	// Material conditions.
	ENUM_CASE(PMIToleranceModifierType,MaterialCondition_Unsupported)
	ENUM_CASE(PMIToleranceModifierType,MaterialCondition_NoModifier)
	ENUM_CASE(PMIToleranceModifierType,MaterialCondition_Maximum)
	ENUM_CASE(PMIToleranceModifierType,MaterialCondition_Least)
	ENUM_CASE(PMIToleranceModifierType,MaterialCondition_RegardlessOfFeatureSize)

	// Tangent planes
	ENUM_CASE(PMIToleranceModifierType,TangentPlane_Unsupported)
	ENUM_CASE(PMIToleranceModifierType,TangentPlane_NotTangent)
	ENUM_CASE(PMIToleranceModifierType,TangentPlane_Tangent)

	// Free State
	ENUM_CASE(PMIToleranceModifierType,FreeState_Unsupported)
	ENUM_CASE(PMIToleranceModifierType,FreeState_Free)
	ENUM_CASE(PMIToleranceModifierType,FreeState_NotFree)

	//ST symbol
	ENUM_CASE(PMIToleranceModifierType,Statistical_Symbol)

	//Common Zone
	ENUM_CASE(PMIToleranceModifierType,CommonZone)


	//Unequally Disposed Tolerance Zone
	ENUM_CASE(PMIToleranceModifierType,UnequallyDisposedZone)

	// Projected State
	ENUM_CASE(PMIToleranceModifierType,ProjectedState_Projected)
	ENUM_CASE(PMIToleranceModifierType,ProjectedState_NotProjected)

	// Circle U 
	ENUM_CASE(PMIToleranceModifierType,CircleU)

	ENUM_CASE(PMIToleranceModifierType,Maximum)
	ENUM_CASE(PMIToleranceModifierType,MinimaxFeature)
	ENUM_CASE(PMIToleranceModifierType,DerivedFeature)
	ENUM_CASE(PMIToleranceModifierType,DynamicProfile)
	ENUM_CASE(PMIToleranceModifierType,LeastSquareFeature)
	ENUM_CASE(PMIToleranceModifierType,MaximumInscribedFeature)
	ENUM_CASE(PMIToleranceModifierType,MinimumCircumscribedFeature)

	ENUM_CASE(PMIToleranceModifierType,SeparateZone)
	ENUM_CASE(PMIToleranceModifierType,OffsetZone)
	ENUM_CASE(PMIToleranceModifierType,VariableAngle)
	ENUM_CASE(PMIToleranceModifierType,OrientationConstraint)
	ENUM_CASE(PMIToleranceModifierType,MinimaxAssociation)
	ENUM_CASE(PMIToleranceModifierType,MinimaxAssociationWithExternalConstraint)
	ENUM_CASE(PMIToleranceModifierType,MinimaxAssociationWithInternalConstraint)
	ENUM_CASE(PMIToleranceModifierType,LeastSquareAssociation)
	ENUM_CASE(PMIToleranceModifierType,LeastSquareAssociationWithExternalConstraint)
	ENUM_CASE(PMIToleranceModifierType,LeastSquareAssociationWithInternalConstraint)
	ENUM_CASE(PMIToleranceModifierType,MinimumCircumscribedAssociation)
	ENUM_CASE(PMIToleranceModifierType,MaximumInscribedAssociation)
	ENUM_CASE(PMIToleranceModifierType,TotalRangeOfDeviations)
	ENUM_CASE(PMIToleranceModifierType,PeakHeight)
	ENUM_CASE(PMIToleranceModifierType,ValleyDepth)
	ENUM_CASE(PMIToleranceModifierType,StandardDeviation)
)

class PMIZoneModifier {
public:
    void SetZoneModifierType(const PMIToleranceModifierType &t){
        this->zoneModifierType = t ; 
    } ;
    void SetZoneModifierMagnitudeValue(double t){
        this->zoneModifierMagnitudeValue = t ; 
    } ;

    PMIToleranceModifierType GetZoneModifierType() const {
        return this->zoneModifierType;
    }

    double GetZoneModifierMagnitudeValue() const {
        return this->zoneModifierMagnitudeValue;
    }

    std::string ToString() ;
private:
    PMIToleranceModifierType zoneModifierType ;
    double zoneModifierMagnitudeValue ;
} ;

class PMIModifiedDatum{
public:
    void AddZoneModifier(const PMIZoneModifier &zoneModifier) {
        this->zoneModifiers.push_back(zoneModifier) ;
    }
    std::string ToString() ;
private:
    std::vector<PMIZoneModifier> zoneModifiers ;
} ;

class DatumRef {

public:

    void SetLabel(const std::string & l){
        this->label = l ;
    } ;

    void SetText(const ExchangePMIText &t){
        this->text = t ;
    }

    void AddModifierDatum(const PMIModifiedDatum &pmiModifierDatum){
        this->pmiModifierDatums.push_back(pmiModifierDatum) ;
    }

    std::string ToString() ;
    
private:
    std::string label ;
    ExchangePMIText text ;
    std::vector<PMIModifiedDatum> pmiModifierDatums ;
} ;

class GDTRefFrame{
public:
    void SetLabel(const std::string &label){
        this->label = label ; 
    } ;
    void AddDatumRef(const std::shared_ptr<DatumRef> &datumRef){
        this->datumRefs.push_back(datumRef) ;
    } ;

    std::string ToString() ;
private:
    std::string label ;
    std::vector<std::shared_ptr<DatumRef>> datumRefs ;
} ;

class ExchangeGDTRow
{
public:
    void SetToleranceValueType(const PMIToleranceValueType &t){
        this->modifierType = t ; 
    } ;

    void SetToleranceValue(double t){
        this->toleranceMagnitudeValue = t ; 
    } ;
    void SetRefinementToleranceValue(double t){
        this->refinementToleranceValue = t ; 
    } ;
    void SetRateUnit1(double t){
        this->rateUnit1 = t ; 
    } ;
    void SetRateUnit2(double t){
        this->rateUnit2 = t ; 
    } ;
    void AddZoneModifier(const PMIZoneModifier &zoneModifier){
        this->zoneModifiers.push_back(zoneModifier) ;
    } ;

    void SetGDTRefFrame(const std::shared_ptr<GDTRefFrame> &gdtRefFrame){
        this->gdtRefFrame = gdtRefFrame ;
    } ;

    std::string ToString() ;
private:
    PMIToleranceValueType modifierType ;
    double toleranceMagnitudeValue ;
    double refinementToleranceValue ;
    double rateUnit1 ;
    double rateUnit2 ;
    std::vector<PMIZoneModifier> zoneModifiers ;

    std::shared_ptr<GDTRefFrame> gdtRefFrame ;
} ;
    
class ExchangeGDT : public ExchangePMIAnnotation
{
public:
    PMIAnnotationType GetType() const override
	{
		return PMIAnnotationType::GDT;
	} 

    void SetToleranceType(const PMIToleranceType &t){
        this->toleranceType = t ; 
    } ;
    void SetToleranceValueType(const PMIToleranceValueType &t){
        this->valueType = t ; 
    } ;
    void SetToleranceValue(double t){
        this->toleranceValue = t ; 
    } ;
    void SetRefinementToleranceValue(double t){
        this->refinementToleranceValue = t ; 
    } ;
    void SetRateUnit1(double t){
        this->rateUnit1 = t ; 
    } ;
    void SetRateUnit2(double t){
        this->rateUnit2 = t ; 
    } ;
    void SetProjectedToleranceLength(double t){
        this->projectedToleranceLength = t ; 
    } ;
    void SetProfileShiftValue(double t){
        this->profileShiftValue = t ; 
    } ;
    void SetAllAround(bool t){
        this->allAround = t ; 
    } ;
    void SetNote(const std::string &t){
        this->note = t ; 
    } ;
    void SetNoteText(const ExchangePMIText &t){
        this->noteText = t ; 
    } ;

    void AddGDTRow(const ExchangeGDTRow &gdtRow){
        this->gdtRows.push_back(gdtRow) ;
    } ;

    std::string ToString() override ;
private:
    PMIToleranceType toleranceType ;
    PMIToleranceValueType valueType ;
    double toleranceValue ;
    double refinementToleranceValue ;
    double rateUnit1 ;
    double rateUnit2 ;
    double projectedToleranceLength ;
    double profileShiftValue ;
    bool allAround ;
    std::string note ;

    ExchangePMIText noteText ;

    std::vector<ExchangeGDTRow> gdtRows ;

    
} ;

}
#endif